﻿using ICSharpCode.AvalonEdit;
using MahApps.Metro.Controls.Dialogs;
using Newtonsoft.Json;
using PDFDesign.Command;
using PDFDesign.Common;
using PDFDesign.Model;
using PDFDesign.Repository;
using PDFDesign.Window;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;

namespace PDFDesign.ViewModel
{
    public class NewDesignViewModel : BaseViewModel
    {
        private readonly TextEditor textEditor;
        private readonly TreeView treeView;
        private readonly TabControl tabNode;
        private readonly List<TreeNodeType> DeAddNodeList = new List<TreeNodeType>
        {
            TreeNodeType.Table,
            TreeNodeType.PageSetting,
            TreeNodeType.Column,
            TreeNodeType.Control,
            TreeNodeType.Cell
        };
        private readonly List<TreeNodeType> DeDelNodeList = new List<TreeNodeType>
        {
            TreeNodeType.Table,
            TreeNodeType.PageSetting,
            TreeNodeType.Controls,
            TreeNodeType.Columns,
            TreeNodeType.Rows,
            TreeNodeType.FixedRows
        };
        private readonly List<TreeNodeType> DeSaveNodeList = new List<TreeNodeType>
        {
            TreeNodeType.Controls,
            TreeNodeType.Columns,
            TreeNodeType.FixedRows,
            TreeNodeType.Rows
        };

        public NewDesignViewModel(NewDesignWindow window)
        {
            textEditor = window.textEditor;
            treeView = window.treeView;
            tabNode = window.tabNode;
            RefreshStyleList();
        }

        private string searchTemplateName;
        /// <summary>
        /// 模板关键词
        /// </summary>
        public string SearchTemplateName
        {
            get => searchTemplateName;
            set
            {
                searchTemplateName = value;
                OnPropertyChanged("SearchTemplateName");
            }
        }

        private ObservableCollection<NewStyleViewModel> reportStyles = new ObservableCollection<NewStyleViewModel>();
        /// <summary>
        /// 样式列表
        /// </summary>
        public ObservableCollection<NewStyleViewModel> ReportStyles
        {
            get => reportStyles;
            set
            {
                reportStyles = value;
                OnPropertyChanged("ReportStyles");
            }
        }

        private NewStyleViewModel selectStyle;
        /// <summary>
        /// 选择样式
        /// </summary>
        public NewStyleViewModel SelectStyle
        {
            get => selectStyle;
            set
            {
                selectStyle = value;
                CurrentStyle = value;
                OnPropertyChanged("SelectStyle");
            }
        }

        private NewStyleViewModel currentStyle;
        /// <summary>
        /// 当前样式
        /// </summary>
        public NewStyleViewModel CurrentStyle
        {
            get => currentStyle;
            set
            {
                currentStyle = value;
                OnPropertyChanged("CurrentStyle");
                if (currentStyle == null)
                {
                    StyleContent = "";
                    TreeNodeList = new ObservableCollection<TreeNodeModel>();
                    return;
                }
                StyleContent = Utils.Format(currentStyle.ReportStyle.Content, true, out _);
                TreeNodeList = TreeNodeModel.Convert(currentStyle.PDFStyle);
                CurrentNode = null;
                DesignUtils.ClearTreeViewSelection(treeView);
            }
        }

        private string styleContent = "";
        /// <summary>
        /// 样式信息
        /// </summary>
        public string StyleContent
        {
            get => styleContent;
            set
            {
                styleContent = value;
                textEditor.Text = styleContent;
                OnPropertyChanged("StyleContent");
            }
        }

        private bool isSource;
        /// <summary>
        /// 是否为源代码
        /// </summary>
        public bool IsSource
        {
            get => isSource;
            set
            {
                if (SelectStyle == null) return;
                if (isSource)
                {
                    var pdfStyle = Utils.Deserialize<NewStyle>(textEditor.Text, out bool success);
                    if (!success)
                    {
                        ShowMessage("JSON格式有误，请检查");
                        return;
                    }
                    currentStyle.PDFStyle = pdfStyle;
                    TreeNodeList = TreeNodeModel.Convert(currentStyle.PDFStyle);
                    CurrentNode = null;
                    DesignUtils.ClearTreeViewSelection(treeView);
                }
                else
                {
                    var pdfStyle = GetPDFStyle();
                    StyleContent = Utils.Format(JsonConvert.SerializeObject(pdfStyle), true, out bool _);
                }
                isSource = value;
                CurrentIndex = isSource ? 1 : 0;
                OnPropertyChanged("IsSource");
            }
        }

        private int currentIndex;
        /// <summary>
        /// 当前页面索引
        /// </summary>
        public int CurrentIndex
        {
            get => currentIndex;
            set
            {
                currentIndex = value;
                OnPropertyChanged("CurrentIndex");
            }
        }

        private ObservableCollection<TreeNodeModel> treeNodeList = new ObservableCollection<TreeNodeModel>();
        /// <summary>
        /// 节点树
        /// </summary>
        public ObservableCollection<TreeNodeModel> TreeNodeList
        {
            get => treeNodeList;
            set
            {
                treeNodeList = value;
                OnPropertyChanged("TreeNodeList");
            }
        }

        private TreeNodeModel currentNode;
        /// <summary>
        /// 当前节点
        /// </summary>
        public TreeNodeModel CurrentNode
        {
            get => currentNode;
            set
            {
                currentNode = value;
                OnPropertyChanged("CurrentNode");
                ChoiceNodeItem();
            }
        }

        private PageSettingViewModel pageSetting;
        /// <summary>
        /// PageSetting
        /// </summary>
        public PageSettingViewModel PageSetting
        {
            get => pageSetting;
            set
            {
                pageSetting = value;
                OnPropertyChanged("PageSetting");
            }
        }

        private ControlViewModel control;
        /// <summary>
        /// Control
        /// </summary>
        public ControlViewModel Control
        {
            get => control;
            set
            {
                control = value;
                OnPropertyChanged("Control");
            }
        }

        private TableViewModel table;
        /// <summary>
        /// Table
        /// </summary>
        public TableViewModel Table
        {
            get => table;
            set
            {
                table = value;
                OnPropertyChanged("Table");
            }
        }

        private ColumnViewModel column;
        /// <summary>
        /// Column
        /// </summary>
        public ColumnViewModel Column
        {
            get => column;
            set
            {
                column = value;
                OnPropertyChanged("Column");
            }
        }

        private RowViewModel row;
        /// <summary>
        /// Row
        /// </summary>
        public RowViewModel Row
        {
            get => row;
            set
            {
                row = value;
                OnPropertyChanged("Row");
            }
        }

        private CellViewModel cell;
        /// <summary>
        /// Cell
        /// </summary>
        public CellViewModel Cell
        {
            get => cell;
            set
            {
                cell = value;
                OnPropertyChanged("Cell");
            }
        }

        /// <summary>
        /// 节点选择
        /// </summary>
        private void ChoiceNodeItem()
        {
            if (CurrentNode == null)
            {
                EnabledSave = EnabledAdd = EnabledDel = false;
                TabItemIndex = 0;
                return;
            }
            EnabledAdd = !DeAddNodeList.Contains(CurrentNode.TreeNodeType);
            EnabledDel = !DeDelNodeList.Contains(CurrentNode.TreeNodeType);
            EnabledSave = !DeSaveNodeList.Contains(CurrentNode.TreeNodeType);
            switch (CurrentNode.TreeNodeType)
            {
                case TreeNodeType.PageSetting:
                    TabItemIndex = 1;
                    PageSetting = new PageSettingViewModel((PageSetting)CurrentNode.Tag);
                    break;
                case TreeNodeType.Control:
                    TabItemIndex = 2;
                    Control = new ControlViewModel((Model.Control)CurrentNode.Tag);
                    break;
                case TreeNodeType.Table:
                    TabItemIndex = 3;
                    Table = new TableViewModel((Table)CurrentNode.Tag);
                    break;
                case TreeNodeType.Column:
                    TabItemIndex = 4;
                    Column = new ColumnViewModel((Column)CurrentNode.Tag);
                    break;
                case TreeNodeType.Row:
                    TabItemIndex = 5;
                    Row = new RowViewModel((Row)CurrentNode.Tag);
                    break;
                case TreeNodeType.Cell:
                    TabItemIndex = 6;
                    Cell = new CellViewModel((Cell)CurrentNode.Tag);
                    break;
                default:
                    TabItemIndex = 0;
                    break;
            }
        }

        private bool enabledAdd = false;
        /// <summary>
        /// 启用添加
        /// </summary>
        public bool EnabledAdd
        {
            get => enabledAdd;
            set
            {
                enabledAdd = value;
                OnPropertyChanged("EnabledAdd");
            }
        }

        private bool enabledDel = false;
        /// <summary>
        /// 启用删除
        /// </summary>
        public bool EnabledDel
        {
            get => enabledDel;
            set
            {
                enabledDel = value;
                OnPropertyChanged("EnabledDel");
            }
        }

        private bool enabledSave = false;
        /// <summary>
        /// 启用保存
        /// </summary>
        public bool EnabledSave
        {
            get => enabledSave;
            set
            {
                enabledSave = value;
                OnPropertyChanged("EnabledSave");
            }
        }

        private int tabItemIndex = 0;
        /// <summary>
        /// 选项卡索引
        /// </summary>
        public int TabItemIndex
        {
            get => tabItemIndex;
            set
            {
                tabItemIndex = value;
                OnPropertyChanged("TabItemIndex");
            }
        }

        /// <summary>
        /// 移除样式
        /// </summary>
        public ICommand RemoveSelectedItemCommand => new AnotherCommand(async _ =>
        {
            if (SelectStyle == null)
            {
                await ShowMessage("请选择需要删除的样式");
                return;
            }
            var result = await ShowMessageBox($"是否确定删除({currentStyle.ReportStyle.TemplateName}-{currentStyle.ReportStyle.StyleName})?");
            if (result == MessageDialogResult.Negative) return;
            ReportStyleRepository.GetInstance().Delete(SelectStyle.ReportStyle.Id);
            RefreshStyleList();
        });

        /// <summary>
        /// 刷新样式
        /// </summary>
        public ICommand RefreshCommand => new AnotherCommand(_ => RefreshStyleList());

        private void RefreshStyleList()
        {
            try
            {
                var reportStyles = ReportStyleRepository.GetInstance().GetReportStyleList(SearchTemplateName);
                ReportStyles = new ObservableCollection<NewStyleViewModel>();
                int i = 0;
                reportStyles.ForEach(style =>
                {
                    NewStyle pdfStyle = null;
                    try
                    {
                        pdfStyle = JsonConvert.DeserializeObject<NewStyle>(style.Content);
                    }
                    catch (Exception) { }
                    if (pdfStyle == null) return;
                    ReportStyles.Add(new NewStyleViewModel
                    {
                        Num = ++i,
                        ReportStyle = style,
                        PDFStyle = pdfStyle
                    });
                });
                CurrentStyle = null;
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
            }
        }

        /// <summary>
        /// 格式化
        /// </summary>
        public ICommand FormatCommand => new AnotherCommand(_ => StyleContent = Utils.Format(textEditor.Text, true, out bool _));

        /// <summary>
        /// 主题设置
        /// </summary>
        public ICommand ThemeSettingCommand => new AnotherCommand(_ => new PaletteWindow().ShowDialog());

        /// <summary>
        /// 获取帮助
        /// </summary>
        public ICommand GetHelpCommand => new AnotherCommand(_ => Process.Start("tencent://Message/?Uin=935411557&websiteName=blog.silkage.net&Menu=yes"));

        /// <summary>
        /// 帮助文档
        /// </summary>
        public ICommand DocumentCommand => new AnotherCommand(_ => Process.Start("https://www.wsgjp.com/"));

        /// <summary>
        /// 添加样式
        /// </summary>
        public ICommand AddCommand => new AnotherCommand(_ =>
        {
            var window = new CreateStyleWindow();
            var viewModel = new CreateStyleViewModel(window.textEditor);
            window.DataContext = viewModel;
            var flag = window.ShowDialog();
            if (flag.HasValue && flag.Value)
            {
                RefreshStyleList();
                SelectStyle = viewModel.NewStyleViewModel;
            }
        });

        /// <summary>
        /// 添加节点
        /// </summary>
        public ICommand AddNodeCommand => new AnotherCommand(async _ =>
        {
            if (CurrentNode == null || DeAddNodeList.Contains(CurrentNode.TreeNodeType)) return;
            var name = string.Empty;
            if (CurrentNode.TreeNodeType != TreeNodeType.Rows && CurrentNode.TreeNodeType != TreeNodeType.FixedRows)
            {
                name = await ShowInputDialog("PDF样式设计工具", "请输入控件名称");
                if (name == null) return;
                if (string.IsNullOrWhiteSpace(name))
                {
                    await ShowMessage("控件名称不能为空");
                    return;
                }
            }
            TreeNodeModel treeNodeModel = null;
            switch (CurrentNode.TreeNodeType)
            {
                case TreeNodeType.Controls:
                    var control = Model.Control.Default(name);
                    treeNodeModel = new TreeNodeModel
                    {
                        TreeNodeType = TreeNodeType.Control,
                        Name = $"Control[{control.Name}]",
                        Tag = control,
                        Parent = CurrentNode
                    };
                    ((List<Model.Control>)CurrentNode.Tag).Add(control);
                    break;
                case TreeNodeType.Columns:
                    var column = Model.Column.Default(name);
                    treeNodeModel = new TreeNodeModel
                    {
                        TreeNodeType = TreeNodeType.Column,
                        Name = $"Column[{name}]",
                        Tag = column,
                        Parent = CurrentNode
                    };
                    ((List<Column>)CurrentNode.Tag).Add(column);
                    break;
                case TreeNodeType.Rows:
                case TreeNodeType.FixedRows:
                    var row = Model.Row.Default;
                    treeNodeModel = new TreeNodeModel
                    {
                        TreeNodeType = TreeNodeType.Row,
                        Name = "Row",
                        Tag = row,
                        Parent = CurrentNode,
                        Children = new ObservableCollection<TreeNodeModel>()
                    };
                    ((List<Row>)CurrentNode.Tag).Add(row);
                    break;
                case TreeNodeType.Row:
                    var cell = Model.Cell.Default(name);
                    treeNodeModel = new TreeNodeModel
                    {
                        TreeNodeType = TreeNodeType.Cell,
                        Name = $"Cell[{name}]",
                        Tag = cell,
                        Parent = CurrentNode
                    };
                    ((Row)CurrentNode.Tag).Cells.Add(cell);
                    break;
            }
            if (treeNodeModel == null) return;
            CurrentNode.Children.Add(treeNodeModel);
        });

        /// <summary>
        /// 删除节点
        /// </summary>
        public ICommand DelNodeCommand => new AnotherCommand(async _ =>
        {
            if (CurrentNode == null || DeDelNodeList.Contains(CurrentNode.TreeNodeType)) return;
            var result = await ShowMessageBox("删除操作不可逆，确认删除?");
            if (result == MessageDialogResult.Negative) return;
            switch (CurrentNode.TreeNodeType)
            {
                case TreeNodeType.Control:
                    ((List<Model.Control>)CurrentNode.Parent.Tag).Remove((Model.Control)CurrentNode.Tag);
                    break;
                case TreeNodeType.Column:
                    ((List<Column>)CurrentNode.Parent.Tag).Remove((Column)CurrentNode.Tag);
                    break;
                case TreeNodeType.Row:
                    ((List<Row>)CurrentNode.Parent.Tag).Remove((Row)CurrentNode.Tag);
                    break;
                case TreeNodeType.Cell:
                    ((Row)CurrentNode.Parent.Tag).Cells.Remove((Cell)CurrentNode.Tag);
                    break;
            }
            CurrentNode.Parent.Children.Remove(CurrentNode);
            CurrentNode = null;
        });

        /// <summary>
        /// 保存节点
        /// </summary>
        public ICommand SaveNodeCommand => new AnotherCommand(_ =>
        {
            if (CurrentNode == null || DeSaveNodeList.Contains(CurrentNode.TreeNodeType)) return;
            // 更新TextBox控件值
            DesignUtils.FindVisualChildren<TextBox>(tabNode).ToList().ForEach(tb => tb.GetBindingExpression(TextBox.TextProperty)?.UpdateSource());
            switch (CurrentNode.TreeNodeType)
            {
                case TreeNodeType.PageSetting: PageSetting.Save(); break;
                case TreeNodeType.Control: Control.Save(); break;
                case TreeNodeType.Table: Table.Save(); break;
                case TreeNodeType.Column: Column.Save(); break;
                case TreeNodeType.Row: Row.Save(); break;
                case TreeNodeType.Cell: Cell.Save(); break;
            }
        });

        /// <summary>
        /// 保存样式
        /// </summary>
        public ICommand SaveCommand => new AnotherCommand(_ =>
        {
            if (SelectStyle == null || CurrentStyle == null) return;
            var json = string.Empty;
            if (IsSource)
            {
                json = Utils.Format(textEditor.Text, false, out bool success);
                if (!success)
                {
                    ShowMessage("JSON格式有误，请检查");
                    return;
                }
            }
            else
            {
                var pdfStyle = GetPDFStyle();
                json = Utils.Serialize(pdfStyle, out bool _);
            }
            CurrentStyle.ReportStyle.Content = json;
            var res = ReportStyleRepository.GetInstance();
            var flag = res.Update(currentStyle.ReportStyle);
            ShowMessage("样式更新" + (flag ? "成功" : "失败"));
            RefreshStyleList();
        });

        /// <summary>
        /// 设置模拟数据
        /// </summary>
        public ICommand SetDataCommand => new AnotherCommand(_ => new MockDataWindow().ShowDialog());

        private ViewWindow viewWindow;
        /// <summary>
        /// 预览
        /// </summary>
        public ICommand PreviewCommand => new AnotherCommand(async _ =>
        {
            if (CurrentStyle == null)
            {
                await ShowMessage("请选择样式后预览");
                return;
            }
            var dataList = DesignUtils.GetSaveDataList();
            var data = dataList.FirstOrDefault(d => d.Name == CurrentStyle.ReportStyle.TemplateName);
            if (data == null)
            {
                await ShowMessage("模拟数据不存在，请先添加模拟数据");
                new MockDataWindow().ShowDialog();
                return;
            }
            var reportData = JsonConvert.DeserializeObject<dynamic>(data.Data);
            var style = GetPDFStyle();
            var key = Utils.Push(reportData, style);
            if (string.IsNullOrWhiteSpace(key))
            {
                await ShowMessage("提交渲染任务异常");
                return;
            }
            var viewViewModel = ViewViewModel.GetInstance();
            if (viewWindow == null)
            {
                viewWindow = new ViewWindow
                {
                    DataContext = viewViewModel
                };
                viewWindow.Closed += (sender, e) => viewWindow = null;
                viewWindow.Show();
            }
            viewViewModel.Url = $"{Utils.Host}render?key={key}&r={new Random().NextDouble()}";
        });

        /// <summary>
        /// TreeNodeList转样式实体
        /// </summary>
        /// <returns></returns>
        private NewStyle GetPDFStyle()
        {
            var pdfStyle = new NewStyle();
            TreeNodeList.ToList().ForEach(node =>
            {
                if (node.TreeNodeType == TreeNodeType.PageSetting)
                {
                    pdfStyle.PageSetting = (PageSetting)node.Tag;
                }
                else if (node.TreeNodeType == TreeNodeType.Controls)
                {
                    pdfStyle.Controls = (List<Model.Control>)node.Tag;
                }
                else if (node.TreeNodeType == TreeNodeType.Table)
                {
                    pdfStyle.Table = (Table)node.Tag;
                }
            });
            return pdfStyle;
        }
    }
}
